import {ArgumentMetadata, BadRequestException, PipeTransform, Injectable} from "@nestjs/common";
import {plainToInstance} from 'class-transformer'
import {validate, ValidationError} from 'class-validator'

export class ValidationPipe implements PipeTransform {
    async transform(value: any, metadata: ArgumentMetadata): Promise<any> {
        // 可能方法没有设置类型不需要校验
        if (!metadata.metatype || this.needValidate(metadata.metatype)) return value;

        // 此处的value只是一个普通的对象 == plain对象
        const instance = plainToInstance(metadata.metatype, value);
        const errors = await validate(instance)

        if (errors.length) {
            throw new BadRequestException(this.formatErrors(errors))
        } else {
            return value;
        }
    }

    // 原有自带类型不需要校验，不是dto类型的
    private needValidate(metatype: Function): Boolean {
        const types: Function[] = [String, Boolean, Number, Array, Object]
        return types.includes(metatype);
    }

    private formatErrors(errors: ValidationError[]): string[] {
        return errors.map((error)=>{
            for(const property in error.constraints){
                return `${error.property} - ${error.constraints[property]}`
            }
        })
    }
}
